home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Games / NetHack 3.1.3 / source / sys / unix / unixmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-01  |  9.6 KB  |  439 lines  |  [TEXT/R*ch]

  1. /*    SCCS Id: @(#)unixmain.c    3.1    92/12/04    */
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. /* main.c - Unix NetHack */
  6.  
  7. #include "hack.h"
  8.  
  9. #include <signal.h>
  10. #include <pwd.h>
  11. #ifndef O_RDONLY
  12. #include <fcntl.h>
  13. #endif
  14.  
  15. #if !defined(_BULL_SOURCE) && !defined(sgi) && !defined(_M_UNIX)
  16. # if defined(POSIX_TYPES) || defined(SVR4) || defined(HPUX)
  17. extern struct passwd *FDECL(getpwuid,(uid_t));
  18. # else
  19. extern struct passwd *FDECL(getpwuid,(int));
  20. # endif
  21. #endif
  22. extern struct passwd *FDECL(getpwnam,(const char *));
  23. #ifdef CHDIR
  24. static void chdirx();
  25. #endif /* CHDIR */
  26. static boolean whoami();
  27. static void FDECL(process_options, (int, char **));
  28.  
  29. #ifdef _M_UNIX
  30. extern void NDECL(check_sco_console);
  31. extern void NDECL(init_sco_cons);
  32. #endif
  33.  
  34. int
  35. main(argc,argv)
  36. int argc;
  37. char *argv[];
  38. {
  39.     register int fd;
  40. #ifdef CHDIR
  41.     register char *dir;
  42. #endif
  43.     boolean exact_username;
  44.  
  45.     hname = argv[0];
  46.     hackpid = getpid();
  47.     (void) umask(0);
  48.  
  49.     choose_windows(DEFAULT_WINDOW_SYS);
  50.  
  51. #ifdef CHDIR            /* otherwise no chdir() */
  52.     /*
  53.      * See if we must change directory to the playground.
  54.      * (Perhaps hack runs suid and playground is inaccessible
  55.      *  for the player.)
  56.      * The environment variable HACKDIR is overridden by a
  57.      *  -d command line option (must be the first option given)
  58.      */
  59.     dir = getenv("NETHACKDIR");
  60.     if (!dir) dir = getenv("HACKDIR");
  61. #endif
  62.     if(argc > 1) {
  63. #ifdef CHDIR
  64.         if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
  65.         /* avoid matching "-dec" for DECgraphics; since the man page
  66.          * says -d directory, hope nobody's using -desomething_else
  67.          */
  68.         argc--;
  69.         argv++;
  70.         dir = argv[0]+2;
  71.         if(*dir == '=' || *dir == ':') dir++;
  72.         if(!*dir && argc > 1) {
  73.             argc--;
  74.             argv++;
  75.             dir = argv[0];
  76.         }
  77.         if(!*dir)
  78.             error("Flag -d must be followed by a directory name.");
  79.         } else
  80. #endif /* CHDIR /**/
  81.  
  82.     /*
  83.      * Now we know the directory containing 'record' and
  84.      * may do a prscore().
  85.      */
  86.         if (!strncmp(argv[1], "-s", 2)) {
  87. #ifdef CHDIR
  88.         chdirx(dir,0);
  89. #endif
  90.         prscore(argc, argv);
  91.         exit(0);
  92.         }
  93.     }
  94.  
  95. #ifdef _M_UNIX
  96.     check_sco_console();
  97. #endif
  98.     initoptions();
  99.     init_nhwindows();
  100.     exact_username = whoami();
  101. #ifdef _M_UNIX
  102.     init_sco_cons();
  103. #endif
  104.  
  105.     /*
  106.      * It seems you really want to play.
  107.      */
  108.     setrandom();
  109.     u.uhp = 1;    /* prevent RIP on early quits */
  110.     (void) signal(SIGHUP, (SIG_RET_TYPE) hangup);
  111. #ifdef SIGXCPU
  112.     (void) signal(SIGXCPU, (SIG_RET_TYPE) hangup);
  113. #endif
  114.  
  115.     /*
  116.      * Find the creation date of this game,
  117.      * so as to avoid restoring outdated savefiles.
  118.      */
  119.     gethdate(hname);
  120.  
  121.     /*
  122.      * We cannot do chdir earlier, otherwise gethdate will fail.
  123.      */
  124. #ifdef CHDIR
  125.     chdirx(dir,1);
  126. #endif
  127.  
  128.     process_options(argc, argv);    /* command line options */
  129.  
  130. #ifdef DEF_PAGER
  131.     if(!(catmore = getenv("HACKPAGER")) && !(catmore = getenv("PAGER")))
  132.         catmore = DEF_PAGER;
  133. #endif
  134. #ifdef MAIL
  135.     getmailstatus();
  136. #endif
  137. #ifdef WIZARD
  138.     if (wizard)
  139.         Strcpy(plname, "wizard");
  140.     else
  141. #endif
  142.     if(!*plname || !strncmp(plname, "player", 4)
  143.             || !strncmp(plname, "games", 4)) {
  144.         askname();
  145.     } else if (exact_username) {
  146.         /* guard against user names with hyphens in them */
  147.         int len = strlen(plname);
  148.         /* append the current role, if any, so that last dash is ours */
  149.         if (++len < sizeof plname)
  150.             (void)strncat(strcat(plname, "-"),
  151.                       pl_character, sizeof plname - len - 1);
  152.     }
  153.     plnamesuffix();        /* strip suffix from name; calls askname() */
  154.                 /* again if suffix was whole name */
  155.                 /* accepts any suffix */
  156. #ifdef WIZARD
  157.     if(!wizard) {
  158. #endif
  159.         /*
  160.          * check for multiple games under the same name
  161.          * (if !locknum) or check max nr of players (otherwise)
  162.          */
  163.         (void) signal(SIGQUIT,SIG_IGN);
  164.         (void) signal(SIGINT,SIG_IGN);
  165.         if(!locknum)
  166.             Sprintf(lock, "%d%s", (int)getuid(), plname);
  167.         getlock();
  168. #ifdef WIZARD
  169.     } else {
  170.         Sprintf(lock, "%d%s", (int)getuid(), plname);
  171.         getlock();
  172.     }
  173. #endif /* WIZARD /**/
  174.  
  175.     /*
  176.      * Initialisation of the boundaries of the mazes
  177.      * Both boundaries have to be even.
  178.      */
  179.  
  180.     x_maze_max = COLNO-1;
  181.     if (x_maze_max % 2)
  182.         x_maze_max--;
  183.     y_maze_max = ROWNO-1;
  184.     if (y_maze_max % 2)
  185.         y_maze_max--;
  186.  
  187.     /*
  188.      *  Initialize the vision system.  This must be before mklev() on a
  189.      *  new game or before a level restore on a saved game.
  190.      */
  191.     vision_init();
  192.  
  193.     display_gamewindows();
  194.  
  195.     set_savefile_name();
  196.     uncompress(SAVEF);
  197.  
  198.     if((fd = open_savefile()) >= 0 &&
  199.        /* if not up-to-date, quietly delete file via false condition */
  200.        (uptodate(fd) || delete_savefile())) {
  201. #ifdef WIZARD
  202.         /* Since wizard is actually flags.debug, restoring might
  203.          * overwrite it.
  204.          */
  205.         boolean remember_wiz_mode = wizard;
  206. #endif
  207.         (void) chmod(SAVEF,0);    /* disallow parallel restores */
  208.         (void) signal(SIGINT, (SIG_RET_TYPE) done1);
  209. #ifdef NEWS
  210.         if(flags.news) {
  211.             display_file(NEWS, FALSE);
  212.             flags.news = FALSE; /* in case dorecover() fails */
  213.         }
  214. #endif
  215.         pline("Restoring save file...");
  216.         mark_synch();    /* flush output */
  217.         if(!dorecover(fd))
  218.             goto not_recovered;
  219. #ifdef WIZARD
  220.         if(!wizard && remember_wiz_mode) wizard = TRUE;
  221. #endif
  222.         pline("Hello %s, welcome back to NetHack!", plname);
  223.         check_special_room(FALSE);
  224. #ifdef EXPLORE_MODE
  225.         if (discover)
  226.             You("are in non-scoring discovery mode.");
  227. #endif
  228. #if defined(EXPLORE_MODE) || defined(WIZARD)
  229.         if (discover || wizard) {
  230.             if(yn("Do you want to keep the save file?") == 'n')
  231.                 (void) delete_savefile();
  232.             else {
  233.                 (void) chmod(SAVEF,FCMASK); /* back to readable */
  234.                 compress(SAVEF);
  235.             }
  236.         }
  237. #endif
  238.         flags.move = 0;
  239.     } else {
  240. not_recovered:
  241.         player_selection();
  242.         newgame();
  243.         /* give welcome message before pickup messages */
  244.         pline("Hello %s, welcome to NetHack!", plname);
  245. #ifdef EXPLORE_MODE
  246.         if (discover)
  247.             You("are in non-scoring discovery mode.");
  248. #endif
  249.         flags.move = 0;
  250.         set_wear();
  251.         pickup(1);
  252.     }
  253.  
  254.     flags.moonphase = phase_of_the_moon();
  255.     if(flags.moonphase == FULL_MOON) {
  256.         You("are lucky!  Full moon tonight.");
  257.         change_luck(1);
  258.     } else if(flags.moonphase == NEW_MOON) {
  259.         pline("Be careful!  New moon tonight.");
  260.     }
  261.     if(flags.friday13 = friday_13th()) {
  262.         pline("Watch out!  Bad things can happen on Friday the 13th.");
  263.         change_luck(-1);
  264.     }
  265.  
  266.     initrack();
  267.  
  268.     moveloop();
  269.     return(0);
  270. }
  271.  
  272. static void
  273. process_options(argc, argv)
  274. int argc;
  275. char *argv[];
  276. {
  277.     /*
  278.      * Process options.
  279.      */
  280.     while(argc > 1 && argv[1][0] == '-'){
  281.         argv++;
  282.         argc--;
  283.         switch(argv[0][1]){
  284. #if defined(WIZARD) || defined(EXPLORE_MODE)
  285. # ifndef EXPLORE_MODE
  286.         case 'X':
  287. # endif
  288.         case 'D':
  289. # ifdef WIZARD
  290.             {
  291.               char *user;
  292.               int uid;
  293.               struct passwd *pw = (struct passwd *)0;
  294.  
  295.               uid = getuid();
  296.               user = getlogin();
  297.               if (user) {
  298.                   pw = getpwnam(user);
  299.                   if (pw && (pw->pw_uid != uid)) pw = 0;
  300.               }
  301.               if (pw == 0) {
  302.                   user = getenv("USER");
  303.                   if (user) {
  304.                   pw = getpwnam(user);
  305.                   if (pw && (pw->pw_uid != uid)) pw = 0;
  306.                   }
  307.                   if (pw == 0) {
  308.                   pw = getpwuid(uid);
  309.                   }
  310.               }
  311.               if (pw && !strcmp(pw->pw_name,WIZARD)) {
  312.                   wizard = TRUE;
  313.                   break;
  314.               }
  315.             }
  316.             /* otherwise fall thru to discover */
  317. # endif
  318. # ifdef EXPLORE_MODE
  319.         case 'X':
  320.             discover = TRUE;
  321. # endif
  322.             break;
  323. #endif
  324. #ifdef NEWS
  325.         case 'n':
  326.             flags.news = FALSE;
  327.             break;
  328. #endif
  329.         case 'u':
  330.             if(argv[0][2])
  331.               (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
  332.             else if(argc > 1) {
  333.               argc--;
  334.               argv++;
  335.               (void) strncpy(plname, argv[0], sizeof(plname)-1);
  336.             } else
  337.                 raw_print("Player name expected after -u");
  338.             break;
  339.         case 'I':
  340.         case 'i':
  341.             if (!strncmpi(argv[0]+1, "IBM", 3))
  342.                 switch_graphics(IBM_GRAPHICS);
  343.             break;
  344.         /*  case 'D': */
  345.         case 'd':
  346.             if (!strncmpi(argv[0]+1, "DEC", 3))
  347.                 switch_graphics(DEC_GRAPHICS);
  348.             break;
  349.         default:
  350.             /* allow -T for Tourist, etc. */
  351.             (void) strncpy(pl_character, argv[0]+1,
  352.                 sizeof(pl_character)-1);
  353.  
  354.             /* raw_printf("Unknown option: %s", *argv); */
  355.         }
  356.     }
  357.  
  358.     if(argc > 1)
  359.         locknum = atoi(argv[1]);
  360. #ifdef MAX_NR_OF_PLAYERS
  361.     if(!locknum || locknum > MAX_NR_OF_PLAYERS)
  362.         locknum = MAX_NR_OF_PLAYERS;
  363. #endif
  364. }
  365.  
  366. #ifdef CHDIR
  367. static void
  368. chdirx(dir, wr)
  369. const char *dir;
  370. boolean wr;
  371. {
  372.  
  373. # ifdef SECURE
  374.     if(dir                    /* User specified directory? */
  375. #  ifdef HACKDIR
  376.            && strcmp(dir, HACKDIR)        /* and not the default? */
  377. #  endif
  378.         ) {
  379.         (void) setgid(getgid());
  380.         (void) setuid(getuid());        /* Ron Wessels */
  381.     }
  382. # endif
  383.  
  384. # ifdef HACKDIR
  385.     if(dir == NULL)
  386.         dir = HACKDIR;
  387. # endif
  388.  
  389.     if(dir && chdir(dir) < 0) {
  390.         perror(dir);
  391.         error("Cannot chdir to %s.", dir);
  392.     }
  393.  
  394.     /* warn the player if we can't write the record file */
  395.     /* perhaps we should also test whether . is writable */
  396.     /* unfortunately the access system-call is worthless */
  397.     if (wr) check_recordfile(dir);
  398. }
  399. #endif /* CHDIR /**/
  400.  
  401. static boolean
  402. whoami() {
  403.     /*
  404.      * Who am i? Algorithm: 1. Use name as specified in NETHACKOPTIONS
  405.      *            2. Use $USER or $LOGNAME    (if 1. fails)
  406.      *            3. Use getlogin()        (if 2. fails)
  407.      * The resulting name is overridden by command line options.
  408.      * If everything fails, or if the resulting name is some generic
  409.      * account like "games", "play", "player", "hack" then eventually
  410.      * we'll ask him.
  411.      * Note that we trust the user here; it is possible to play under
  412.      * somebody else's name.
  413.      */
  414.     register char *s;
  415.  
  416.     if (*plname) return FALSE;
  417.     if(/* !*plname && */ (s = getenv("USER")))
  418.         (void) strncpy(plname, s, sizeof(plname)-1);
  419.     if(!*plname && (s = getenv("LOGNAME")))
  420.         (void) strncpy(plname, s, sizeof(plname)-1);
  421.     if(!*plname && (s = getlogin()))
  422.         (void) strncpy(plname, s, sizeof(plname)-1);
  423.     return TRUE;
  424. }
  425.  
  426. #ifdef PORT_HELP
  427. void
  428. port_help()
  429. {
  430.     /*
  431.      * Display unix-specific help.   Just show contents of the helpfile
  432.      * named by PORT_HELP.
  433.      */
  434.     display_file(PORT_HELP, TRUE);
  435. }
  436. #endif
  437.  
  438. /*unixmain.c*/
  439.